﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<functional>
using namespace std;

struct Date
{
	int _year;
	int _month;
	int _day;

	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}

	~Date()
	{
		//cout << "~Date()" << endl;
	}
};

namespace zsy
{
	template<class T>
	class shared_ptr
	{

	public:
		shared_ptr(T* ptr)
			:_ptr(ptr)
			, _pcount(new int(1))
		{}
		
		template<class D>
		shared_ptr(T* ptr, D del)
			:_ptr(ptr)
			, _pcount(new int(1))
			, _del(del)
		{}
		

		shared_ptr(const shared_ptr<T>& sp)
			:_ptr(sp._ptr)
			, _pcount(sp._pcount)
		{
			(*_pcount)++;
		}

		void release()
		{
			//最后一个管理的对象，释放资源 
			if (--(*_pcount) == 0)
			{
				_del(_ptr);
				delete _pcount;
				_ptr = nullptr;
				_pcount = nullptr;
			}
		}

		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			if (_ptr != sp._ptr)
			{
				release();

				_ptr = sp._ptr;
				_pcount = sp._pcount;
				++(*_pcount);
				_del = sp._del;
			}

			return *this;
		}


		~shared_ptr()
		{
			release();
		}
		

		T& operator*()
		{
			return *_ptr;
		}

		T* operator->()
		{
			return _ptr;
		}

		int use_count() const
		{
			return *_pcount;
		}

		T* get() const
		{
			return _ptr;
		}

	private:
		T* _ptr;
		int* _pcount;
		//删除器del: 调用删除器释放资源,管理数组
		function<void(T*)> _del = [](T* ptr) {delete ptr; };
	};
}


//int main()
//{
//	zsy::shared_ptr<Date> sp1(new Date);//构造
//	zsy::shared_ptr<Date> sp2(sp1);//拷贝构造
//	zsy::shared_ptr<Date> sp3(new Date);
//	sp3 = sp2;//拷贝赋值
//
//	sp1->_year++;
//	sp2->_year++;
//	sp3->_year++;
//
//	return 0;
//}


namespace zsy
{
	template<class T>
	class auto_ptr
	{
	public:
		auto_ptr(T* ptr)
			:_ptr(ptr)
		{
			cout << "普通构造" << endl;
		}

		auto_ptr(auto_ptr<T>& ap)
			:_ptr(ap._ptr)
		{
			//管理权转移
			ap._ptr = nullptr;
			cout << "拷贝构造" << endl;
		}

		auto_ptr<T>& operator=(auto_ptr<T>& ap)
		{
			//检测是否自己为自己赋值
			if (this != &ap)
			{
				//释放当前对象中资源
				if (_ptr)
					delete _ptr;

				//转移ap中资源到当前对象中
				_ptr = ap._ptr;
				ap._ptr = nullptr;
			}

			return *this;
		}

		~auto_ptr()
		{
			if (_ptr)
			{
				cout << "delete: " << _ptr << endl;
				delete _ptr;
			}
		}

		//像指针一样使用
		T& operator*()
		{
			return *_ptr;
		}

		T* operator->()
		{
			return _ptr;
		}
	private:
		T* _ptr;
	};
}

//int main()
//{
//	zsy::auto_ptr<Date> ap1(new Date);//构造
//	zsy::auto_ptr<Date> ap2(ap1);//拷贝构造, sp1被悬空
//	zsy::auto_ptr<Date> ap3(new Date);
//	ap3 = ap2;//拷贝赋值,sp2被悬空
//
//	ap3->_year++;
//
//	return 0;
//}

namespace zsy
{
	template<class T>
	class unique_ptr
	{
	public:
		explicit unique_ptr(T* ptr)
			:_ptr(ptr)
		{}

		unique_ptr(const unique_ptr<T>& sp) = delete;//禁用拷贝构造
		unique_ptr<T>& operator=(const unique_ptr<T>& sp) = delete;//禁用拷贝赋值

		//移动构造
		unique_ptr(unique_ptr<T>&& sp)
			:_ptr(sp._ptr)
		{
			sp._ptr = nullptr;
		}

		//移动赋值
		unique_ptr<T>& operator=(unique_ptr<T>&& sp)
		{
			//检查是否自我赋值
			if (this != &sp)
			{
				delete _ptr;
				_ptr = sp._ptr;
				sp._ptr = nullptr;
			}

			return *this;
		}

		~unique_ptr()
		{
			if (_ptr)
			{
				cout << "delete: " << _ptr << endl;
				delete _ptr;
			}
		}
		
		T& operator*()
		{
			return *_ptr;
		}

		T* operator->()
		{
			return _ptr;
		}
	private:
		T* _ptr;
	};
}

namespace zsy
{
	template<class T>
	class weak_ptr
	{
	public:
		weak_ptr()
		{}

		weak_ptr(const shared_ptr<T>& sp)
			:_ptr(sp.get())
		{}

		weak_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			_ptr = sp.get();

			return *this;
		}
	private:
		T* _ptr = nullptr;
	};
}

//int main()
//{
//	zsy::unique_ptr<int> up1(new int(10));//构造
//	zsy::unique_ptr<int> up2 = move(up1);//移动构造: up1的资源转移给up2，up1变为nullptr
//	zsy::unique_ptr<int> up3(new int(20));
//	up3 = move(up2);//移动赋值: up3释放原有资源，接收up2的资源，up2变为nullptr
//
//	return 0;
//}


struct ListNode
{
	int _data;
	//std::shared_ptr<ListNode> _prev;
	//std::shared_ptr<ListNode> _next;

	//这里改成weak_ptr，当n1->_next = n2;绑定shared_ptr时不增加n2的引用计数，
	//不参与资源释放的管理，就不会形成循环引用了 
	std::weak_ptr<ListNode> _prev;
	std::weak_ptr<ListNode> _next;

	~ListNode()
	{
		cout << "~ListNode()" << endl;
	}
};

int main()
{
	std::shared_ptr<ListNode> n1(new ListNode);
	std::shared_ptr<ListNode> n2(new ListNode);
	cout << n1.use_count() << endl;
	cout << n2.use_count() << endl;

	//循环引用 -- 内存泄露 
	n1->_next = n2;
	n2->_prev = n1;
	cout << n1.use_count() << endl;
	cout << n2.use_count() << endl;

	//weak_ptr不支持管理资源，不支持RAII 
    //weak_ptr是专门绑定shared_ptr，不增加他的引用计数，作为⼀些场景的辅助管理 
	std::weak_ptr<ListNode> wp(n1);

	return 0;
}


//int main()
//{
//	std::shared_ptr<int> sp1(new int(1));
//	std::shared_ptr<int> sp2(sp1);
//	std::weak_ptr<int> wp(sp1);
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl << endl;
//
//	//sp1和sp2都指向了其他资源，则weak_ptr就过期了
//	sp1 = make_shared<int>(2);
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl << endl;
//
//	sp2 = make_shared<int>(3);
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl << endl;
//
//	std::shared_ptr<int> sp3 = wp.lock();
//	if (sp3)
//	{
//		cout << wp.expired() << endl;
//		cout << wp.use_count() << endl;
//		*sp3 += 6;
//		cout << *sp3 << endl;
//	}
//	else
//	{
//		cout << "weak_ptr已过期，无法获取有效指针" << endl;
//	}
//
//	return 0;
//}

#include<mutex>
#include<thread>

struct AA
{
	int _a1 = 0;
	int _a2 = 0;

	~AA()
	{
		cout << "~AA()" << endl;
	}
};

//int main()
//{
//	zsy::shared_ptr<AA> p(new AA);
//	const size_t n = 100000;
//	mutex mtx;
//	auto func = [&]()
//		{
//			for (size_t i = 0; i < n; i++)
//			{
//				//这里智能指针拷贝会++计数
//				zsy::shared_ptr<AA> copy(p);
//				{
//					unique_lock<mutex> lt(mtx);
//					copy->_a1++;
//					copy->_a2++;
//				}
//			}
//		};
//
//	thread t1(func);
//	thread t2(func);
//	t1.join();
//	t2.join();
//	cout << p->_a1 << endl;
//	cout << p->_a2 << endl;
//	cout << p.use_count() << endl;
//
//	return 0;
//}

//int main()
//{
//	//申请一个1G未释放,这个程序多次运行也没啥危害
//	//因为程序马上就结束,进程结束各种资源也就回收了
//	char* ptr = new char[1024 * 1024 * 1024];
//	cout << (void*)ptr << endl;
//
//	return 0;
//}

//unique_ptr<Date[]> up1(new Date[5]); 
//shared_ptr<Date[]> sp1(new Date[5]); 
//
//template <class T, class... Args> shared_ptr<T> 
//make_shared(Args&&... args);


template<class T>
void DeleteArrayFunc(T* ptr)
{
	delete[] ptr;
}

template<class T>
class DeleteArray
{
public:
	void operator()(T* ptr)
	{
		delete[] ptr;
	}
};

class Fclose
{
public:
	void operator()(FILE* ptr)
	{
		cout << "fclose: " << ptr << endl;
		fclose(ptr);
	}
};

//int main()
//{
//	//这样使用程序会崩溃
//	//unique_ptr<Date> up1(new Date[10]);  //err
//	//shared_ptr<Date> sp1(new Date[10]);  //err
//
//	//解决方案1
//	//因为new[]经常使用,所以unique_ptr和shared_ptr实现一个特化版本,
//	//这个特化版本析构时用delete[]
//	unique_ptr<Date[]> up1(new Date[10]);
//	shared_ptr<Date[]> sp1(new Date[10]);
//
//	//解决方案2
//	//仿函数对象做删除器
//	std::unique_ptr<Date, DeleteArray<Date>> up(new Date[5], DeleteArray<Date>());
//
//	//unique和shared_ptr支持删除器的方式有所不同
//	//unique的删除器作为模版参数,shared_ptr的删除器作为构造函数参数
//	unique_ptr<Date, DeleteArray<Date>> up2(new Date[5]);
//	shared_ptr<Date> sp2(new Date[5], DeleteArray<Date>());
//
//	//函数指针做删除器
//	unique_ptr<Date, void(*)(Date*)> up3(new Date[5], DeleteArrayFunc<Date>);
//	shared_ptr<Date> sp3(new Date[5], DeleteArrayFunc<Date>);
//
//	//lambda表达式做删除器
//	auto delArrOBJ = [](Date* ptr) {delete[] ptr; };
//	unique_ptr<Date, decltype(delArrOBJ)> up4(new Date[5], delArrOBJ);
//	shared_ptr<Date> sp4(new Date[5], delArrOBJ);
//
//	//实现其他资源管理器的删除器
//	shared_ptr<FILE> sp5(fopen("Test.cpp", "r"), Fclose());
//	shared_ptr<FILE> sp6(fopen("Test.cpp", "r"), [](FILE* ptr)
//		{
//			cout << "fclose: " << ptr << endl;
//			fclose(ptr);
//		});
//
//	return 0;
//}

//int main()
//{
//	shared_ptr<Date> sp1(new Date(2025, 10, 1));
//	shared_ptr<Date> sp2 = make_shared<Date>(2025, 10, 1);
//	auto sp3 = make_shared<Date>(2025, 10, 1);
//	shared_ptr<Date> sp4;
//
//	if (sp1)
//		cout << "sp1 is not nullptr" << endl;
//	if (!sp4)
//		cout << "sp4 is nullptr" << endl;
//
//	return 0;
//}


//struct ListNode
//{
//	int _data;
//	std::shared_ptr<ListNode> _prev;
//	std::shared_ptr<ListNode> _next;
//	//这里改成weak_ptr，当n1->_next = n2;绑定shared_ptr时不增加n2的引用计数，
//	//不参与资源释放的管理，就不会形成循环引用了 
//	/*std::weak_ptr<ListNode> _prev;
//	std::weak_ptr<ListNode> _next;*/
//
//	~ListNode()
//	{
//		cout << "~ListNode()" << endl;
//	}
//};
//
//int main()
//{
//	std::shared_ptr<ListNode> n1(new ListNode);
//	std::shared_ptr<ListNode> n2(new ListNode);
//	cout << n1.use_count() << endl;
//	cout << n2.use_count() << endl;
//
//	//循环引用 -- 内存泄露 
//	n1->_next = n2;
//	n2->_prev = n1;
//	cout << n1.use_count() << endl;
//	cout << n2.use_count() << endl;
//
//	//weak_ptr不支持管理资源，不支持RAII 
//	//weak_ptr是专门绑定shared_ptr，不增加他的引用计数，作为⼀些场景的辅助管理 
//	std::weak_ptr<ListNode> wp(n1);
//
//	return 0;
//}